<!DOCTYPE html>
<html lang="en">

<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>块级作用域</title>
</head>

<body>
  <button>按钮1</button>
  <button>按钮2</button>
  <button>按钮3</button>
  <button>按钮4</button>
  <button>按钮5</button>
</body>

<script>
  // 1. 变量作用域L:变量在什么范围内是可用的
  {
    var name = 'why';
    console.log(name);
    let letName = 'haha';
    console.log(letName);
  }
  console.log(name);
  // 会报错，未定义的letName,超出了letName的定义域
  // console.log(letName);

  // 2. 没有块级作用域引起的问题
  var func;
  if (true) {
    var info = '你好';

    func = function () {
      console.log(info); // 打印你好
    }
    // 调用 
    func();
  }
  // if块之外调用，仍然打印
  func();

  // 3. 没有块级作用域引起的问题：for的块级
  var btns = window.document.getElementsByTagName('button');
  for (var i = 0; i < btns.length; i++) {
    // 为什么闭包可以解决问题：函数是一个作用域，不会被别人改变
    (function (num) { // 闭包开始
      btns[i].addEventListener('click', function () {
        // 存在问题 i 是全局作用域的
        console.log('第' + (num+1) + '个按钮被点击');
      })
    })(i) // 闭包结束
  }

  // ES5及其之前因为if和for都没有块级作用域的概
  // 所以在很多时候，我们都必须要借助function的作用域来解决应用外部变量的问题
</script>

</html>